/* 
 * cms，一个基于J2EE架构内容管理系统
 * Copyright © GrayRabbit Co., Ltd. All rights reserved.
 * Department:运营department
 * 更多信息请访问：
 * http://code.google.com/p/gray-rabbit-cms/
 */
package org.grayrabbit.cms.service.search.impl;

import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.apache.commons.lang.ArrayUtils;
import org.apache.commons.lang.StringUtils;
import org.grayrabbit.cms.constant.ConstantEnum.HotKeywordType;
import org.grayrabbit.cms.dao.search.HotKeywordDao;
import org.grayrabbit.cms.dao.search.HotKeywordRuleDao;
import org.grayrabbit.cms.dao.search.KeywordsDao;
import org.grayrabbit.cms.entity.HotKeyword;
import org.grayrabbit.cms.entity.HotKeywordRule;
import org.grayrabbit.cms.entity.Keywords;
import org.grayrabbit.cms.entity.OperLog;
import org.grayrabbit.cms.service.search.HotKeywordService;
import org.grayrabbit.cms.util.lucene.WordUtil;
import org.grayrabbit.cms.vo.search.HotKeywordBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import org.grayrabbit.dao.util.Page;
import org.grayrabbit.service.impl.GenericServiceImpl;
/**
 * <b>OperLog</b>的service实现类，事务加此处：





 * @version 1.0,创建时间: 2011-05-16 14:51:27  
 */
@Service
@Transactional
public class HotKeywordServiceImpl extends GenericServiceImpl implements HotKeywordService {
	/**
	 * 注入dao层：
	 */
	@Autowired
	@Qualifier("hotKeywordDaoImpl")
	private HotKeywordDao hotKeywordDao;
	
	@Autowired
	@Qualifier("hotKeywordRuleDaoImpl")
	private HotKeywordRuleDao hotKeywordRuleDao;
	
	@Autowired
	@Qualifier("keywordsDaoImpl")
	private KeywordsDao keywordsDao;
	 
	/**
	 * 此方法执行时为只读事务：
	 * @see HotKeywordService#getOperLog(String)
	 */
	@Transactional(readOnly=true)
	public HotKeyword getHotKeyword(final String hotKeywordId){
		HotKeyword hotKeyword = hotKeywordDao.findById(hotKeywordId);
		hotKeywordDao.initialize(hotKeyword);
		return hotKeyword;
	}
	
	/**
	 * @see HotKeywordService#delete(String)
	 */
	@Transactional
	public void delete(final HotKeyword hotKeyword) {
		hotKeywordDao.makeTransient(hotKeyword);
	}
	
	/**
	 * @see HotKeywordService#save(OperLog)
	 */
	@Transactional
	public void save(final HotKeyword hotKeyword) {
		hotKeywordDao.makePersistent(hotKeyword);		
	}
	
	/**
	 * 此方法执行时为只读事务：
	 * @see HotKeywordService#getPage(HotKeywordBean)
	 */
	@Transactional(readOnly=true)
	public Page<HotKeyword> getPage(final HotKeywordBean hotKeywordBean){
		Page<HotKeyword> page =  new Page<HotKeyword>();
		page.setTotal(hotKeywordDao.count(hotKeywordBean));
		page.setResult(hotKeywordDao.findByQc(hotKeywordDao.assembly(hotKeywordBean)));
		return page;
	}

	/**
	 * 此方法执行时为只读事务：
	 * @see HotKeywordService#list(Page, HotKeywordBean)
	 */
	public void list(Page<HotKeyword> page, HotKeywordBean hotKeywordBean) {
		if(page==null)
			return;
		if(page.isAutoCount()){
			page.setTotal(hotKeywordDao.count(hotKeywordBean));
		}
		page.setResult(hotKeywordDao.findByPage(page,hotKeywordBean));
	}
	
	/**
	 * 根据主键id列删除，批量删除OperLog
	 * @see HotKeywordService#delete(String[])
	 */
	public void delete(final String[] key) {
		int i =0;
		for(String id : key){
			hotKeywordDao.makeTransient(hotKeywordDao.findById(id));
			i++;
			if(i==MAX_CLEAR)
				hotKeywordDao.clear();
		}
		
	}

	/**
	 * 检查关键字唯一性
	 */
	public Boolean checkUnique(String hotKeywordName, String hotKeywordId) {
		return hotKeywordDao.checkUnique(hotKeywordName, hotKeywordId);
	}
	/**
	 * 检查文件前缀唯一性
	 */
	public Boolean checkFilenameUnique(String frontFilename, String hotKeywordId) {
		return hotKeywordDao.checkFilenameUnique(frontFilename, hotKeywordId);
	}
	
	@Transactional
	public void handleKeyWord(String[] keys) {
		if(ArrayUtils.isEmpty(keys)) return ;
		/* keys 去重 */
		Set<String> set = new HashSet<String>();
		for(String k:keys){
			set.add(k);
		}
		
		for(String key : set){
			HotKeyword hk =hotKeywordDao.findByKeyWord(key);
			/* 没有此关键词  进行存储  */
			if(hk == null){
				HotKeyword hot = new HotKeyword();
				hot.setFirstTime(new Date());
				hot.setHotKeywordName(key);
				hot.setHotType(HotKeywordType.ONE.getKey());
				hot.setIsGenerate(false);
				hot.setSearchNum(1L);
				hotKeywordDao.makePersistent(hot);
			}else{ 
				boolean flag =  hotTypeHandle(hk);
				if(flag){
					hotKeywordDao.makePersistent(hk);
				}else {
					hotKeywordDao.makeTransient(hk);
				}
			}
		}		
	}
	
	/**true 更新   false  删除*/
	private boolean hotTypeHandle(HotKeyword keyword){
		String hotType = keyword.getHotType().trim();
		boolean del_flag = false;
		Date date_cur = new Date();  
		Date date_key = keyword.getFirstTime();
		/*当前时间与  关键词记录时间的差值*/
		long mill_tip = date_cur.getTime() - date_key.getTime(); 
		
		long ruleNum = loadRuleMapValue(hotType); // 规则查询次数标准
		long keyNum = keyword.getSearchNum();//实际的查询次数
		if(HotKeywordType.FOREVER.getKey().equals(hotType) 
				|| HotKeywordType.CUSTOM.getKey().equals(hotType)){
			keyNum++;
			keyword.setSearchNum(keyNum);
			del_flag = true;
		}else if(HotKeywordType.ONE.getKey().equals(hotType)){
			del_flag  = keywordTypeUpGrade(hotType, ruleNum, keyNum, mill_tip, 
					MILLISECOND_ONE, HotKeywordType.FOUR.getKey(), false,keyword,null); 
		}else if(HotKeywordType.FOUR.getKey().equals(hotType)){
			del_flag  = keywordTypeUpGrade(hotType, ruleNum, keyNum, mill_tip, 
					MILLISECOND_FOUR, HotKeywordType.EIGHT.getKey(),false,keyword,null);
		}else if(HotKeywordType.EIGHT.getKey().equals(hotType)){
			del_flag  = keywordTypeUpGrade(hotType, ruleNum, keyNum, mill_tip, 
					MILLISECOND_EIGHT, HotKeywordType.DAY.getKey(),false,keyword,null);
			//添加到词库
			String words = keyword.getHotKeywordName();
			if(!keywordsDao.isExistWords(null, words)){
				Keywords k = new Keywords();
				k.setKeywords(words);
				k.setIsEnable(true);
				k.setFirstLetter(WordUtil.getFirstLetter(words));
				k.setPinyin(WordUtil.getPinyin(words));
				k.setSplitWords(WordUtil.getSplitWord(words,",",false));
				keywordsDao.makePersistent(k);
			}
			
		}else if(HotKeywordType.DAY.getKey().equals(hotType)){
			del_flag  = keywordTypeUpGrade(hotType, ruleNum, keyNum, mill_tip, 
					MILLISECOND_DAY, HotKeywordType.WEEK.getKey(),true,keyword,date_cur); 
		}else if(HotKeywordType.WEEK.getKey().equals(hotType)){
			del_flag  = keywordTypeUpGrade(hotType, ruleNum, keyNum, mill_tip, 
					MILLISECOND_WEEK, HotKeywordType.MONTH.getKey(),true,keyword,date_cur);
			
		}else if(HotKeywordType.MONTH.getKey().equals(hotType)){
			del_flag  = keywordTypeUpGrade(hotType, ruleNum, keyNum, mill_tip, 
					MILLISECOND_MONTH, HotKeywordType.FOREVER.getKey(),true,keyword,date_cur);
		}
		
		return del_flag;
	}
	
	
	/**  人们关键词 热门级别 升级
	 * @param hotType   关键词原类型
	 * @param ruleNum   关键词规则 升级标准 次数
	 * @param keyNum    关键词 实际查询次数
	 * @param tip	           当前时间与第一次统计 的时间差
	 * @param ruleMill  各级别标准时间差   
	 * @param up		升级到哪个级别
	 * @param mark      是否已经是24小时及更高级别级别
	 * @param key       mark=true 时 ，  key，date 必须赋值
	 * @param date      mark=true 时，  key，date 必须赋值
	 * @return
	 */
	private boolean keywordTypeUpGrade(String hotType ,long ruleNum,
			long keyNum,long tip,long ruleTip,String up,boolean mark,HotKeyword key,Date date){
		boolean flag = false;
		
		if(tip > ruleTip){ //范围外 
			if(mark){
				if(keyNum >= ruleNum){//满足规则  满则规则  等级提升  次数+1 
					flag = true;
					keyNum++;
					hotType = up;
				}else if(keyNum >= (ruleNum/2)  && keyNum < ruleNum){
					flag = true;
					keyNum = 1;
					
				}
			}else{
				if(keyNum >= ruleNum){//满足规则  满则规则  等级提升  次数+1 
					flag = true;
					keyNum++;
					hotType = up;
				}
			}
			
		}else{//1小时范围内  
			flag = true;
			keyNum++; 
			if(keyNum >= ruleNum){//满则规则  等级提升  次数+1 			
				hotType = up;
			}
		}
		key.setSearchNum(keyNum);
		key.setHotType(hotType); 
		return flag;
	} 
	
	private static final long MILLISECOND_ONE = 1*60*60*1000;  // 一小时 的毫秒数
	private static final long MILLISECOND_FOUR = 4*60*60*1000;
	private static final long MILLISECOND_EIGHT = 8*60*60*1000;
	private static final long MILLISECOND_DAY = 24*60*60*1000;
	private static final long MILLISECOND_WEEK = 7*24*60*60*1000;
	private static final long MILLISECOND_MONTH = 30*24*60*60*1000;	
	public static Map<String ,Long> map= new HashMap<String ,Long>();
	private Long loadRuleMapValue(String key){
		if(map.isEmpty()){
			List<HotKeywordRule> list = hotKeywordRuleDao.findAll();
			for(HotKeywordRule rule : list){
				if(StringUtils.isNotBlank(rule.getItemCode()))
					map.put(rule.getItemCode(),Long.valueOf(rule.getItemValue().trim()));
			}
		}
		if(!HotKeywordType.ONE.getKey().equals(key) 
				&& !HotKeywordType.FOUR.getKey().equals(key)
				&& !HotKeywordType.EIGHT.getKey().equals(key)
				&& !HotKeywordType.DAY.getKey().equals(key)
				&& !HotKeywordType.WEEK.getKey().equals(key)
				&& !HotKeywordType.MONTH.getKey().equals(key)){
			return 0L;
		}
		return map.get(key);
	}
    
	
}